package org.budo.mongo.jdbc.driver;

import java.sql.Date;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Time;
import java.sql.Timestamp;

import org.budo.jdbc.driver.AbstractBudoJdbcResultSet;
import org.budo.support.lang.util.StringUtil;

/**
 * @author li
 */
public abstract class BudoMongoJdbcResultSet extends AbstractBudoJdbcResultSet {
    private BudoMongoJdbcResultSetMetaData metaData;

    private boolean lastGotValueWasNull = false;

    public boolean wasNull() throws SQLException {
        return this.lastGotValueWasNull;
    }

    /**
     * 表示上一个被取回的值是否是空
     */
    public void setLastGotValueWasNull(boolean lastGotValueWasNull) {
        this.lastGotValueWasNull = lastGotValueWasNull;
    }

    public void setMetaData(BudoMongoJdbcResultSetMetaData metaData) {
        this.metaData = metaData;
    }

    public ResultSetMetaData getMetaData() throws SQLException {
        return metaData;
    }

    /**
     * @see #wasNull()
     */
    public Object getObject(int columnIndex) throws SQLException {
        ResultSetMetaData metaData = this.getMetaData();
        String columnLabel = metaData.getColumnLabel(columnIndex);
        return this.getObject(columnLabel);
    }

    /**
     * 默认实现
     */
    public Object getObject(String columnLabel) throws SQLException {
        BudoMongoJdbcResultSetMetaData metaData = (BudoMongoJdbcResultSetMetaData) this.getMetaData();
        int columnIndexByLabel = metaData.getColumnIndexByLabel(columnLabel);
        if (columnIndexByLabel > 0) {
            return this.getObject(columnIndexByLabel);
        }

        String[] columnLabels = metaData.columnLabels();
        throw new SQLException("error columnLabel, columnLabel=" + columnLabel + ", columnLabels=" + StringUtil.join(columnLabels));
    }

    public void close() throws SQLException {}

    public int getType() throws SQLException {
        return ResultSet.TYPE_FORWARD_ONLY;
    }

    public int getInt(String columnLabel) throws SQLException {
        Object value = this.getObject(columnLabel);
        if (null == value) {
            return 0;
        }
        if (!(value instanceof Double) && value instanceof Number) {
            return ((Number) value).intValue();
        }
        return (int) value;
    }

    public long getLong(String columnLabel) throws SQLException {
        Object value = this.getObject(columnLabel);
        if (null == value) {
            return 0;
        }
        if (!(value instanceof Double) && value instanceof Number) {
            return ((Number) value).longValue();
        }
        return (long) value;
    }

    public short getShort(String columnLabel) throws SQLException {
        Object value = this.getObject(columnLabel);
        if (null == value) {
            return 0;
        }
        if (!(value instanceof Double) && value instanceof Number) {
            return ((Number) value).shortValue();
        }
        return (short) value;
    }

    public float getFloat(String columnLabel) throws SQLException {
        Object value = this.getObject(columnLabel);
        if (null == value) {
            return 0;
        }
        if (!(value instanceof Double) && value instanceof Number) {
            return ((Number) value).floatValue();
        }
        return (float) value;
    }

    public double getDouble(String columnLabel) throws SQLException {
        Object value = this.getObject(columnLabel);
        if (null == value) {
            return 0;
        }
        if (!(value instanceof Double) && value instanceof Number) {
            return ((Number) value).doubleValue();
        }
        return (double) value;
    }

    public String getString(String columnLabel) throws SQLException {
        Object value = this.getObject(columnLabel);
        return null == value ? null : value.toString();
    }

    public String getString(int columnIndex) throws SQLException {
        Object value = this.getObject(columnIndex);
        return null == value ? null : value.toString();
    }

    public Date getDate(String columnLabel) throws SQLException {
        java.util.Date javaDate = (java.util.Date) this.getObject(columnLabel);
        return null == javaDate ? null : new Date(javaDate.getTime());
    }

    public Date getDate(int columnIndex) throws SQLException {
        java.util.Date javaDate = (java.util.Date) this.getObject(columnIndex);
        return null == javaDate ? null : new Date(javaDate.getTime());
    }

    public Time getTime(String columnLabel) throws SQLException {
        java.util.Date javaDate = (java.util.Date) this.getObject(columnLabel);
        return null == javaDate ? null : new Time(javaDate.getTime());
    }

    public Time getTime(int columnIndex) throws SQLException {
        java.util.Date javaDate = (java.util.Date) this.getObject(columnIndex);
        return null == javaDate ? null : new Time(javaDate.getTime());
    }

    public Timestamp getTimestamp(String columnLabel) throws SQLException {
        java.util.Date javaDate = (java.util.Date) this.getObject(columnLabel);
        return null == javaDate ? null : new Timestamp(javaDate.getTime());
    }

    public Timestamp getTimestamp(int columnIndex) throws SQLException {
        java.util.Date javaDate = (java.util.Date) this.getObject(columnIndex);
        return null == javaDate ? null : new Timestamp(javaDate.getTime());
    }
}